﻿namespace SoundFingerprinting.Audio
{
    using System;
    using ProtoBuf;
    using SoundFingerprinting.Command;

    /// <summary>
    ///  Audio samples that can be used for fingerprinting.
    /// </summary>
    [Serializable]
    [ProtoContract]
    public class AudioSamples
    {
        /// <summary>
        ///  Initializes a new instance of the <see cref="AudioSamples"/> class.
        /// </summary>
        /// <param name="samples">Audio samples.</param>
        /// <param name="origin">Origin identifier (i.e., filename).</param>
        /// <param name="sampleRate">Sample rate of the provided audio samples.</param>
        public AudioSamples(float[] samples, string origin, int sampleRate) : this(samples, origin, sampleRate, DateTime.UtcNow.AddSeconds(-(double)samples.Length / sampleRate), 0)
        {
            // no op
        }

        /// <summary>
        ///  Initializes a new instance of the <see cref="AudioSamples"/> class.
        /// </summary>
        /// <param name="samples">Audio samples.</param>
        /// <param name="origin">Source origin (i.e., filename, URI).</param>
        /// <param name="sampleRate">Sample rate.</param>
        /// <param name="relativeTo">Relative to a particular date time.</param>
        /// <param name="timeOffset">Time offset prefixed to audio samples, used during <see cref="RealtimeQueryCommand"/> to prevent from creating artificial gaps on cut-off times.</param>
        public AudioSamples(float[] samples, string origin, int sampleRate, DateTime relativeTo, double timeOffset = 0)
        {
            Samples = samples;
            Origin = origin;
            SampleRate = sampleRate;
            RelativeTo = relativeTo;
            TimeOffset = timeOffset;
        }

        private AudioSamples()
        {
            // left for serializers
        }

        /// <summary>
        ///  Gets audio samples in Ieee32 format.
        /// </summary>
        [ProtoMember(1)]
        public float[] Samples { get; }

        /// <summary>
        ///  Gets the origin of the audio samples.
        /// </summary>
        [ProtoMember(2)]
        public string Origin { get; }

        /// <summary>
        ///  Gets sample rate at which the audio has been sampled.
        /// </summary>
        [ProtoMember(3)]
        public int SampleRate { get; }

        /// <summary>
        ///  Gets relative to time location when the audio samples have been generated.
        /// </summary>
        [ProtoMember(4)]
        public DateTime RelativeTo { get; }

        /// <summary>
        ///  Gets time offset prefixed to audio samples, used during <see cref="RealtimeQueryCommand"/> to prevent from creating artificial gaps on cut-off times.
        /// </summary>
        /// <remarks>
        ///  Measured in seconds, used only on hashes generated by <see cref="RealtimeQueryCommand"/>.
        /// </remarks>
        [ProtoMember(5)]
        public double TimeOffset { get; }

        /// <summary>
        ///  Gets the duration in seconds of the audio samples.
        /// </summary>
        public double Duration => (double)Samples.Length / SampleRate;
    }
}
